home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / libs / knowhow4 / ask_man.cpp < prev    next >
C/C++ Source or Header  |  1994-10-10  |  20KB  |  725 lines

  1. #include "stdlib.h"
  2. #include "ask_man.h"
  3. #include <dos.h>
  4.  
  5. int indexNo;
  6.  
  7. ////////////////////////////////////////////////////////////////////////////
  8. ////////////////////////////////////////////////////////////////////////////
  9. KH_AskManager::KH_AskManager(char** tableNames, KH_QUERRY** querries, int num)
  10.     {
  11.     unlink("answer.db");
  12.     unlink("answer1.db");
  13.     querryList = querries;
  14.     workTable = NULL;
  15.     answerTable = NULL;
  16.     numberOfTables = num;
  17.     tables = (KH_PXTable**)malloc(num * sizeof(KH_PXTable**));
  18.     for(int i = 0; i < num; i++)
  19.     tables[i] = new KH_PXTable(tableNames[i]);
  20.     }
  21. /////////////////////////////////
  22. KH_AskManager::~KH_AskManager()
  23.     {
  24.     for(int i = 0; i < numberOfTables; i++)
  25.     delete tables[i];
  26.     delete tables;
  27.     delete answerTable;
  28.     delete workTable;
  29.     }
  30.  
  31. /////////////////////////////////
  32. int KH_AskManager::createAnswerTable(int nOT)
  33.     {
  34.     pxErr = PXTblDelete("answer.db");
  35.     KH_STRTABLE* fields = new KH_STRTABLE(0, NULL);
  36.     KH_STRTABLE* types = new KH_STRTABLE(0, NULL);
  37.     int dupNo;               // Number of duplicated fields
  38.     int dupLen;              // Len of addition to fld name (if duplicated)
  39.     char dupBuf[10];         // Buffer for name addition (if duplicated)
  40.     char fld[26];
  41.     for(int i = 0; i < nOT; i++)
  42.     {
  43.     for(int j = 1; j <= tables[i]->nFlds; j++)
  44.         {
  45.         PXFldName(tables[i]->tblHandle, j, 26, fld);
  46.         fields->add(fld);
  47.         char typ[26];
  48.         PXFldType(tables[i]->tblHandle, j, 26, typ);
  49.         types->add(typ);
  50.         }
  51.     }
  52. ////////////////    Test for duplicated field names  ////////////////////
  53.     for(i = 0; i < fields->used; i++)
  54.     {
  55.     dupNo = 0;
  56.     for(int j = i + 1; j < fields->used; j++)
  57.         {
  58.         if(!strcmp((*fields)[i], (*fields)[j]))
  59.         dupNo++;
  60.         else
  61.         continue;
  62.         if(dupNo != 0)
  63.         {
  64.         int l = strlen((*fields)[j]);
  65.         dupLen = strlen(itoa(dupNo, dupBuf, 10));
  66.         fields->strings[j] = (char*)realloc(fields->strings[j],
  67.                   l + dupLen + 1);
  68.         strcpy(fields->strings[j] + l, dupBuf);
  69.         fields->strings[j][l + dupLen] = '\0';
  70.         }
  71.  
  72.         }
  73.     }
  74. //////////////////////// End of duplication test /////////////////////////
  75.     if((pxErr = PXTblCreate("answer.db", fields->used, fields->strings,
  76.                 types->strings))    != PXSUCCESS)
  77.     {
  78.     delete fields;
  79.     delete types;
  80.     return 0;
  81.     }
  82.  
  83.     delete fields;
  84.     delete types;
  85.     return 1;
  86.     }
  87.  
  88. /////////////////////////////////
  89. int KH_AskManager::checkQuerry()
  90.     {
  91.     int totalCheckers = 0;
  92. /*  First of all we check the number of checked or calculated fields
  93.        in the querry. Querry with no checked fields is invalid.
  94. */
  95.     for(int i = 0; i < numberOfTables; i++)
  96.     for(int j = 1; j <= tables[i]->nFlds; j++)
  97.         {
  98.         if(querryList[i]->checkedFields[j] != QFREE)
  99.         {
  100.         totalCheckers++;
  101.         break;
  102.         }
  103.         }
  104.     if(!totalCheckers)
  105.     {
  106.     khPxErr = 1;
  107.     return 0;
  108.     }
  109. /*    Then we iterates EXAMPLES.
  110.      Second table MUST contain common variable(s)
  111.      with 1-st, third - with the 1-st or 2-nd and so on. If this
  112.      condition fails, querry fails too, because one of tables is not
  113.      linked with others.
  114. */
  115.     if(numberOfTables == 1)
  116.     return 1;
  117.     for(i = 1; i < numberOfTables; i++)
  118.     for(int k = 0; k < querryList[i]->examples->used; k++)
  119.         for(int j = 0; j < i; j++)
  120.         for(int l = 0; l < querryList[j]->examples->used; l++)
  121.             if(!strcmp((*(querryList[j]->examples))[l],
  122.                   (*(querryList[i]->examples))[k]))
  123.             return 1;
  124.     khPxErr = 2;
  125.     return 0;
  126.     }
  127. /////////////////////////////////
  128. KH_STRTABLE* KH_AskManager::makeQuerry(int n)
  129.     {
  130.     KH_STRTABLE* retQuerry = new KH_STRTABLE(0, NULL);
  131.  
  132.     int qnum = 0;
  133.     for(int i = 0; i < tables[n]->nFlds; i++)
  134.     if(querryList[n]->querryNumbers[0] != NULL
  135.         && querryList[n]->querryNumbers[qnum] == i)
  136.         {
  137.         retQuerry->add((*(querryList[n]->querry))[qnum]);
  138.         qnum++;
  139.         }
  140.     else
  141.         retQuerry->add("");
  142.     return retQuerry;
  143.     }
  144.  
  145. /////////////////////////////////
  146. int KH_AskManager::processSingleTable()
  147.     {
  148.     KH_STRTABLE* completeQuerry = makeQuerry(0);
  149.     int result;
  150.     KH_PXFLD* ret;
  151.     int r = 0;
  152.  
  153.     while(result = tables[0]->Find(completeQuerry->strings))
  154.     {
  155.     pxErr = PXRecBufCopy(tables[0]->recHandle, answerTable->recHandle);
  156.  
  157.     if((pxErr = PXRecAppend(answerTable->tblHandle, answerTable->recHandle))
  158.         != PXSUCCESS)
  159.         break;
  160.     r = 1;
  161.     if(result == 2)
  162.         break;
  163.     }
  164.  
  165.     delete completeQuerry;
  166.     return r;
  167.     }
  168. /////////////////////////////////
  169. KH_STRTABLE* KH_AskManager::getCurrExamples(int n)
  170.     {
  171.     KH_STRTABLE* ret = new KH_STRTABLE(0, NULL);
  172.  
  173.     int eNum = 0;
  174.     for(int j = 0; j < tables[n]->nFlds; j++)
  175.     {
  176.     if(querryList[n]->exampleNumbers[eNum] == j)
  177.         ret->add((*(querryList[n]->examples))[eNum]);
  178.     else
  179.         ret->add("");
  180.     }
  181.     return ret;
  182.     }
  183. /////////////////////////////////
  184. KH_STRTABLE* KH_AskManager::getExamples(int n)
  185.     {
  186.     KH_STRTABLE* ret = new KH_STRTABLE(0, NULL);
  187.  
  188.     int eNum = 0;
  189.     for(int i = 0; i < n; i++)
  190.     for(int j = 0; j < tables[i]->nFlds; j++)
  191.         {
  192.         if(querryList[i]->exampleNumbers[eNum] == j)
  193.         ret->add((*(querryList[i]->examples))[eNum]);
  194.         else
  195.         ret->add("");
  196.         }
  197.     return ret;
  198.     }
  199.  
  200. /////////////////////////////////
  201. int KH_AskManager::getExSrc(KH_STRTABLE* ex, KH_STRTABLE* cur, int* eNums,
  202.                 FIELDHANDLE* exFlds)
  203.     {
  204.     int k = 0;
  205.     for(int i = 0; i < cur->used; i++)
  206.     for(int j = 0; j < ex->used; j++)
  207.         {
  208.         if((*ex)[j][0] == '\0'
  209.         || strcmp((*ex)[j], ((*cur)[i])))
  210.         continue;
  211.  
  212.         eNums[k] = i + 1;
  213.         eNums[k + 1] = j + 1;
  214.         exFlds[k / 2] = j + 1;
  215.         k += 2;
  216.         }
  217.     return k;
  218.     }
  219. /////////////////////////////////
  220. int KH_AskManager::moveToRec(int* eNums, int numEx, int n, int mode,
  221.     FIELDHANDLE compSecIndexHandle)
  222.     {
  223.     char fieldType[20];
  224.     char _fieldType[20];
  225.     RECORDHANDLE rch;
  226.     pxErr = PXRecBufOpen(workTable->tblHandle, &rch);
  227.     for(int i = 0; i < numEx; i += 2)
  228.     {
  229.     pxErr = PXFldType(workTable->tblHandle, eNums[i + 1], 20,
  230.         fieldType);
  231.     pxErr = PXFldType(tables[n]->tblHandle, eNums[i], 20,
  232.         _fieldType);
  233.     if(fieldType[0] != _fieldType[0])
  234.         {
  235.         khPxErr = 3;
  236.         pxErr = PXRecBufClose(rch);
  237.         return 0;
  238.         }
  239.     switch(fieldType[0])
  240.         {
  241.         case 'A':
  242.         char buf1[255];
  243.         pxErr = PXGetAlpha(tables[n]->recHandle, eNums[i],
  244.                    255, buf1);
  245.         pxErr = PXPutAlpha(rch, eNums[i + 1], buf1);
  246.         break;
  247.         case 'N':
  248.         double d1;
  249.         pxErr = PXGetDoub(tables[n]->recHandle, eNums[i], &d1);
  250.         pxErr = PXPutDoub(rch, eNums[i + 1], d1);
  251.         break;
  252.         case 'S':
  253.         short sh1;
  254.         pxErr = PXGetShort(tables[n]->recHandle, eNums[i], &sh1);
  255.         pxErr = PXPutShort(rch, eNums[i + 1], sh1);
  256.         break;
  257.         case 'D':
  258.         long date1;
  259.         pxErr = PXGetDate(tables[n]->recHandle, eNums[i], &date1);
  260.         pxErr = PXPutDate(rch, eNums[i + 1], date1);
  261.         break;
  262.         default:
  263.         break;
  264.         }
  265.     }
  266.     if((pxErr = PXSrchFld(workTable->tblHandle, rch, compSecIndexHandle, mode))
  267.     != PXSUCCESS)
  268.     {
  269.     pxErr = PXRecBufClose(rch);
  270.     return 0;
  271.     }
  272.  
  273.     pxErr = PXRecBufClose(rch);
  274.     return 1;
  275.     }
  276. ////////////////////////////
  277. void KH_AskManager::writeField(KH_PXTable* srcTable, KH_PXTable* destTable)
  278.     {
  279.     BLOBHANDLE srcBlob;
  280.     BLOBHANDLE destBlob;
  281.  
  282.     unsigned long size;
  283.     unsigned int workSize;
  284.  
  285.     pxErr = PXBlobOpenRead(srcTable->recHandle, srcTable->fldHandle, &srcBlob);
  286.     pxErr = PXBlobGetSize(srcBlob, &size);
  287.     pxErr = PXBlobOpenWrite(destTable->recHandle, destTable->fldHandle,
  288.                 &srcBlob, size, PXBLOBNEW);
  289.     if(size > 65520)
  290.     workSize = 65520;
  291.     else
  292.     workSize = size;
  293.     char* buff = new char[workSize];
  294.     for(long off = 0; off + workSize <= size; off += workSize)
  295.     {
  296.     pxErr = PXBlobGet(srcBlob, workSize, off, buff);
  297.     pxErr = PXBlobPut(destBlob, workSize, off, buff);
  298.     if(size - off > 65520)
  299.         workSize = 65520;
  300.     else
  301.         workSize = size;
  302.     }
  303.     pxErr = PXBlobClose(srcBlob, PXBLOBREJECT);
  304.     pxErr = PXBlobClose(destBlob, PXBLOBACCEPT);
  305.     delete buff;
  306.     }
  307. ////////////////////////////
  308. int KH_AskManager::processMultipleTables()
  309.     {
  310.     char buf[255];                       // String field of KH_PXFLD structure
  311.     KH_PXFLD* retFld = new KH_PXFLD(buf);// Structure returned by getField in
  312.                      // the process of ANSWER building
  313.     int eNums[510];                      // EXAMPLES intersections
  314.     FIELDHANDLE exFlds[255];
  315.  
  316.     for(int i = 1; i < numberOfTables; i++)    // Sequential processing
  317.     {                                      // i == 1 <= we skip 0th table
  318.     KH_STRTABLE* ex = getExamples(i);           // Examples in ANSWER
  319.     KH_STRTABLE* cur = getCurrExamples(i);      // and in current table
  320.     int numEx;
  321.     if(!(numEx = getExSrc(ex, cur, eNums, exFlds)))// eNums contains pares:
  322.         {                          // field No of workTable and of
  323.         delete retFld;             // tables[i] containing examples with
  324.         delete cur;                // same names. NumEx is 0 if no
  325.         delete ex;                 // intersections find (error), or
  326.         return 0;                  // 2 * number of examples on success.
  327.         }                          // exFlds contains ANSWER EX index flds
  328.  
  329.     delete answerTable;                    // Old ANSWER will be replaced
  330.     delete workTable;
  331.     pxErr = PXTblRename("answer.db", "answer1.db");
  332.  
  333.     char nm[10];
  334.     itoa(indexNo, nm, 10);
  335.     indexNo++;
  336.     FIELDHANDLE compSecIndexHandle;
  337.     pxErr = PXKeyMap("answer1.db", numEx / 2, exFlds, nm, 0,
  338.         &compSecIndexHandle);
  339.     exFlds[0] = compSecIndexHandle;
  340.  
  341.     pxErr = PXKeyAdd("answer1.db", 1, exFlds, SECONDARY);
  342.  
  343.     if(!createAnswerTable(i + 1))          // Create new ANSWER table
  344.         {                                  // return on fail
  345.         delete retFld;
  346.         delete cur;
  347.         delete ex;
  348.         return 0;
  349.         }
  350.     answerTable = new KH_PXTable("answer.db");  // Build new temp. tables
  351.     workTable = new KH_PXTable("answer1.db", compSecIndexHandle);
  352.  
  353.     KH_STRTABLE* completeQuerry = makeQuerry(i); // Unpacked querry
  354.  
  355.     RECORDNUMBER recNumber;
  356.     pxErr = PXRecFirst(tables[i]->tblHandle);
  357.  
  358.     while((pxErr = PXRecGet(tables[i]->tblHandle, tables[i]->recHandle))
  359.            == PXSUCCESS)
  360.         {
  361.         int mode = SEARCHFIRST;
  362.         pxErr = PXRecFirst(workTable->tblHandle);
  363.         while(moveToRec(eNums, numEx, i, mode, compSecIndexHandle)
  364.         && (pxErr = PXRecGet(workTable->tblHandle,
  365.             workTable->recHandle) == PXSUCCESS))
  366.         {
  367.         mode = SEARCHNEXT;
  368.         if(!tables[i]->testQuerry(completeQuerry->strings))
  369.             break;
  370.         for(int number = 1; number <= workTable->nFlds; number++)
  371.             {
  372.             workTable->setFld(number);
  373.             answerTable->setFld(number);
  374.  
  375.             if(workTable->getField(retFld) == KH_BLOB)
  376.             writeField(workTable, answerTable);
  377.             else
  378.             answerTable->putField(retFld);
  379.             }
  380.         for(int number1 = number, num = 1;
  381.             number1 <= number + tables[i]->nFlds; number1++, num++)
  382.             {
  383.             tables[i]->setFld(num);
  384.             answerTable->setFld(number1);
  385.             if(tables[i]->getField(retFld) == KH_BLOB)
  386.             writeField(tables[i], answerTable);
  387.             else
  388.             answerTable->putField(retFld);
  389.             }
  390.         if((pxErr = PXRecAppend(answerTable->tblHandle,
  391.                     answerTable->recHandle))
  392.             != PXSUCCESS)
  393.             {
  394.             delete retFld;
  395.             delete completeQuerry;
  396.             delete cur;
  397.             delete ex;
  398.             return 0;
  399.             }
  400.         }
  401.         if((pxErr = PXRecNext(tables[i]->tblHandle)) != PXSUCCESS)
  402.         break;
  403.         }
  404.     delete completeQuerry;
  405.     delete cur;
  406.     delete ex;
  407.     }
  408.  
  409.     delete retFld;
  410.     return 1;
  411.     }
  412. /////////////////////////////////
  413. void KH_AskManager::dumpAnswer()
  414.     {
  415.     char buf[255];                       // String field of KH_PXFLD structure
  416.     KH_PXFLD* retFld = new KH_PXFLD(buf);
  417.     delete workTable;
  418.     pxErr = PXTblDelete("answer1.db");
  419.     KH_STRTABLE* fields = new KH_STRTABLE(0, NULL);
  420.     KH_STRTABLE* types = new KH_STRTABLE(0, NULL);
  421.  
  422.     int srcNo = 1;
  423.     char fld[26];
  424.     char typ[26];
  425.     for(int i = 0; i < numberOfTables; i++)
  426.     {
  427.     for(int j = 1; j <= tables[i]->nFlds; j++)
  428.         {
  429.         if(querryList[i]->checkedFields[j] != '\0')
  430.         {
  431.         PXFldName(answerTable->tblHandle, srcNo, 26, fld);
  432.         fields->add(fld);
  433.         PXFldType(answerTable->tblHandle, srcNo, 26, typ);
  434.         types->add(typ);
  435.         srcNo++;
  436.         }
  437.         }
  438.     }
  439.  
  440.     workTable = new KH_PXTable("answer1.db", 0, fields->used,
  441.             fields->strings, types->strings);
  442.  
  443.     pxErr = PXRecFirst(answerTable->tblHandle);
  444.     int fNo;
  445.  
  446.     while((pxErr = PXRecGet(answerTable->tblHandle,
  447.                 answerTable->recHandle)) == PXSUCCESS)
  448.     {
  449.     srcNo = fNo = 1;
  450.     for(i = 0; i < numberOfTables; i++)
  451.         {
  452.         for(int j = 1; j <= tables[i]->nFlds; j++)
  453.         {
  454.         if(querryList[i]->checkedFields[j] != '\0')
  455.             {
  456.             answerTable->setFld(srcNo);
  457.             workTable->setFld(fNo);
  458.             if(answerTable->getField(retFld) == KH_BLOB)
  459.             writeField(answerTable, workTable);
  460.             else
  461.             workTable->putField(retFld);
  462.             fNo++;
  463.             }
  464.         srcNo++;
  465.         }
  466.         }
  467.     pxErr = PXRecAppend(workTable->tblHandle, workTable->recHandle);
  468.     if((pxErr = PXRecNext(answerTable->tblHandle)) != PXSUCCESS)
  469.         break;
  470.  
  471.     }
  472.     delete retFld;
  473.     delete fields;
  474.     delete types;
  475.     delete workTable;
  476.     delete answerTable;
  477.     pxErr = PXTblRename("answer1.db", "answer.db");
  478.     workTable = NULL;
  479.     answerTable = NULL;
  480.     }
  481. /////////////////////////////////
  482. int KH_AskManager::process()
  483.     {
  484.     if(!checkQuerry())                                 // Verification.
  485.     return 0;
  486.  
  487.     if(!createAnswerTable(1))                           // Create ANSWER table
  488.     return 0;
  489.     answerTable = new KH_PXTable("answer.db");
  490.     int ret = processSingleTable();
  491.  
  492.     if(ret && numberOfTables > 1)
  493.     ret = processMultipleTables();
  494.  
  495.     dumpAnswer();
  496.  
  497.     return ret;
  498.     }
  499.  
  500.  
  501.  
  502.  
  503. #include <iostream.h>
  504. #include <time.h>
  505. /////////////////////
  506. /*
  507. void main()
  508.     {
  509. // Init PARADOX ENGINE
  510.     if(PXInit() != PXSUCCESS)
  511.     return;
  512. // Process single-table querry to DEMO.DB table
  513.     char* tableNames[] = { "demo.db" };                   // Table name
  514.  
  515.     char* q[] = { "", "", "", "", "", "", "", "", "" };   // Querries
  516.     char* e[] = { "", "", "", "", "", "", "", "", "" };   // Examples
  517.     char* c = "\2\2\2\2\2\2\2\2\2\2\0";                   // Checkers
  518.  
  519.     KH_QUERRY* querry1 = new KH_QUERRY(q, e, c, 5);       // Build querry
  520.     KH_QUERRY* querries[2];                               // Querry list
  521.     querries[0] = querry1;
  522.     KH_AskManager* ask = new KH_AskManager(tableNames, querries, 1);
  523.  
  524.     ask->process();                    // Process querry, get ANSWER table
  525. ////////////
  526.  
  527.     KH_PXTable table("answer.db");
  528.  
  529.     char* shablon[] = { "", "", "", "", "", "", "", "", "", "", "" };
  530.     char buf[255];
  531.     int eot;
  532.     while(table.Find(shablon) == 1)
  533.     {
  534.     for(int i = 2; i < 5; i++)
  535.         {
  536.         table.setFld(i);
  537.         table.TranslateField(buf);
  538.         cout << buf << '\t';
  539.         }
  540.     cout << "\n";
  541.     }
  542.  
  543.  
  544.     delete ask;
  545.     delete querry1;
  546.  
  547.     unlink("answer.db");
  548.     PXExit();
  549.     }
  550. */
  551.  
  552. void main()
  553.     {
  554. // Init PARADOX ENGINE
  555.     if(PXInit() != PXSUCCESS)
  556.     return;
  557.     indexNo = 0;     // ATTENTION !!! Absolutely necessary for multytable
  558.              // querries.
  559. // Process single-table querry to DEMO.DB table
  560.     char* tableNames[] = { "demo.db", "demo.db", "demo.db" };                   // Table name
  561.  
  562.     char* q[] = { "", "", "", "", "", "", "", "", "" };   // Querries
  563.     char* e[] = { "", "", "X", "", "", "", "", "", "" };   // Examples
  564.     char* c = "\2\2\2\2\2\2\2\2\2\2\0";                   // Checkers
  565.  
  566.     KH_QUERRY* querry1 = new KH_QUERRY(q, e, c, 5);       // Build querry
  567.     KH_QUERRY* querries[3];                               // Querry list
  568.     querries[0] = querry1;
  569.     querries[1] = querry1;
  570.     querries[2] = querry1;
  571.     KH_AskManager* ask = new KH_AskManager(tableNames, querries, 3);
  572.  
  573.     time_t first, second;
  574.  
  575.     first = time(NULL);
  576.     ask->process();                    // Process querry, get ANSWER table
  577.     second = time(NULL);
  578.     cout << "\nProcessing time = " << difftime(second,first) << " seconds \n";
  579. ////////////
  580.  
  581.     KH_PXTable table("answer.db");
  582.  
  583.     char* shablon[] = { "", "", "", "", "", "", "", "", "", "", "", "", "",
  584.      "", "", "", "", "", "", "", "", "", "", "", "", "" };
  585.     char buf[255];
  586.     int eot;
  587.     long l = 0;
  588.     while(table.Find(shablon) == 1)
  589.     {
  590.     for(int i = 1; i < 16; i++)
  591.         {
  592.         table.setFld(i);
  593.         table.TranslateField(buf);
  594.         cout << i << ": " << buf << "\n";
  595.         }
  596.     cout << "<<<<<<<<<<<<<  RECORD " << l << " >>>>>>>>>>>>>>>>\n";
  597.     l++;
  598.     }
  599.  
  600.  
  601.     delete ask;
  602.     delete querry1;
  603.  
  604.     unlink("answer.db");
  605.     PXExit();
  606.     }
  607.  
  608. /*
  609. void main()     // Add operations on BLOB fields
  610.     {
  611. // Init PARADOX ENGINE
  612.     if(PXInit() != PXSUCCESS)
  613.     return;
  614. // Process single-table querry to DEMO.DB table
  615.     char* tableNames[] = { "demo.db" };                   // Table name
  616.  
  617.     char* q[] = { "", "", "", "", "", "", "", "", "" };   // Querries
  618.     char* e[] = { "", "", "", "", "", "", "", "", "" };   // Examples
  619.     char* c = "\2\2\2\2\2\2\2\2\2\2\0";                   // Checkers
  620.  
  621.     KH_QUERRY* querry1 = new KH_QUERRY(q, e, c, 5);       // Build querry
  622.     KH_QUERRY* querries[2];                               // Querry list
  623.     querries[0] = querry1;
  624.     KH_AskManager* ask = new KH_AskManager(tableNames, querries, 1);
  625.  
  626.     ask->process();                    // Process querry, get ANSWER table
  627. ////////////
  628.  
  629.     KH_PXTable table("answer.db");
  630.  
  631.     char* shablon[] = { "", "", "", "", "", "", "", "", "", "", "" };
  632.     char buf[255];
  633.     char buf1[255];
  634.     int eot;
  635.     KH_PXFLD* retFld = new KH_PXFLD(buf1);
  636.     while(table.Find(shablon) == 1)
  637.     {
  638.     for(int i = 1; i < 6; i++)
  639.         {
  640.         table.setFld(i);
  641.         if(table.TranslateField(buf) == KH_BLOB)
  642.         {
  643.         table.getField(retFld);
  644.         cout << "***************** BLOB: " << retFld->str << "\n";
  645.         }
  646.         else
  647.         cout << buf << "\n";
  648.         }
  649.     cout << "<<<<<<<<<<<<<<<<<<<<<<<<\n";
  650.     }
  651.  
  652.     delete retFld;
  653.     delete ask;
  654.     delete querry1;
  655.  
  656.     unlink("answer.db");
  657.     PXExit();
  658.     }
  659. */
  660. /*
  661. void main()
  662.     {
  663. // Init PARADOX ENGINE
  664.     if(PXInit() != PXSUCCESS)
  665.     return;
  666.     indexNo = 0;     // ATTENTION !!! Absolutely necessary for multytable
  667.              // querries.
  668.     char buf1[255];
  669.     KH_PXFLD* retFld = new KH_PXFLD(buf1);
  670.  
  671. // Process single-table querry to DEMO.DB table
  672.     char* tableNames[] = { "demo.db", "demo.db", "demo.db" };                   // Table name
  673.  
  674.     char* q[] = { "", "", "", "", "", "", "", "", "" };   // Querries
  675.     char* e[] = { "", "", "X", "", "", "", "", "", "" };   // Examples
  676.     char* c = "\2\2\2\2\2\2\2\2\2\2\0";                   // Checkers
  677.  
  678.     KH_QUERRY* querry1 = new KH_QUERRY(q, e, c, 5);       // Build querry
  679.     KH_QUERRY* querries[3];                               // Querry list
  680.     querries[0] = querry1;
  681.     querries[1] = querry1;
  682.     querries[2] = querry1;
  683.     KH_AskManager* ask = new KH_AskManager(tableNames, querries, 3);
  684.  
  685.     time_t first, second;
  686.  
  687.     first = time(NULL);
  688.     ask->process();                    // Process querry, get ANSWER table
  689.     second = time(NULL);
  690.     cout << "\nProcessing time = " << difftime(second,first) << " seconds \n";
  691. ////////////
  692.  
  693.     KH_PXTable table("answer.db");
  694.  
  695.     char* shablon[] = { "", "", "", "", "", "", "", "", "", "", "", "", "",
  696.      "", "", "", "", "", "", "", "", "", "", "", "", "" };
  697.     char buf[255];
  698.     int eot;
  699.     long l = 0;
  700.     while(table.Find(shablon) == 1)
  701.     {
  702.     for(int i = 1; i < 16; i++)
  703.         {
  704.         table.setFld(i);
  705.         if(table.TranslateField(buf) == KH_BLOB)
  706.         {
  707.         table.getField(retFld);
  708.         cout << "***************** BLOB: " << retFld->str << "\n";
  709.         }
  710.         else
  711.         cout << i << ": " << buf << "\n";
  712.         }
  713.     cout << "<<<<<<<<<<<<<  RECORD " << l << " >>>>>>>>>>>>>>>>\n";
  714.     l++;
  715.     }
  716.  
  717.     delete retFld;
  718.     delete ask;
  719.     delete querry1;
  720.  
  721.     unlink("answer.db");
  722.     PXExit();
  723.     }
  724.  
  725. */